package com.huiquan.section.service;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.huiquan.analysis.domain.User;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.base.ReturnCode;
import com.huiquan.framework.base.ReturnData;
import com.huiquan.framework.dao.StaticDataDao;
import com.huiquan.framework.domain.StaticData;
import com.huiquan.framework.utils.GetListUtil;
import com.huiquan.framework.utils.RespHeaderUtil;
import com.huiquan.framework.utils.ReturnUtil;
import com.huiquan.medicine.entity.MedicineGroup;
import com.huiquan.section.dao.SectionBlackDao;
import com.huiquan.section.dao.SectionDao;
import com.huiquan.section.domain.Section;
import com.huiquan.section.domain.SectionBlack;
import com.huiquan.section.domain.SectionDnnDisable;

@Service
public class SectionBlackService extends BaseService {

	@Autowired
	private SectionBlackDao sectionBlackDao;
	@Autowired
	private SectionDao sectionDao;
	@Autowired
	private StaticDataDao staticDataDao;
	public ModelAndView list(String startStr, String nameKey, String exactSearchFlag, String countPerPageStr,String section,String oldSection) {

		Map<String, Object> param = new HashMap<>();
		if (nameKey != null && !nameKey.isEmpty()) {
			if (exactSearchFlag != null && exactSearchFlag.equals("1")) {
				param.put("diseaseName", nameKey);
			} else {
				param.put("diseaseName", "%" + nameKey + "%");
			}
		}
		if (section != null && !section.isEmpty()) {
			if (exactSearchFlag != null && exactSearchFlag.equals("1")) {
				param.put("section", section);
			} else {
				param.put("section", "%" + section + "%");
			}
		}
		if (oldSection != null && !oldSection.isEmpty()) {
			if (exactSearchFlag != null && exactSearchFlag.equals("1")) {
				param.put("oldSection", oldSection);
			} else {
				param.put("oldSection", "%" + oldSection + "%");
			}
		}
		int totalSize = sectionBlackDao.retrieveSize(param);

		Map<String, Integer> pageNo;
		if (countPerPageStr != null && !countPerPageStr.isEmpty()) {
			int countPerPage = Integer.parseInt(countPerPageStr);
			pageNo = GetListUtil.getPageNoParam(totalSize, startStr, countPerPage);
			param.put("countPerPage", countPerPage);
		} else {
			pageNo = GetListUtil.getPageNoParam(totalSize, startStr);
		}
		int endPage = pageNo.get("endPage");
		int start = pageNo.get("start");
		int startIndex = pageNo.get("startIndex");

		List<SectionBlack> list = new ArrayList<>();

		if (startIndex < totalSize) {
			param.put("startIndex", startIndex);
			list = sectionBlackDao.retrievesList(param);
		}

		Map<String, String> showSearch = new LinkedHashMap<>();
		showSearch.put("nameKey", "疾病名称");
		showSearch.put("section","正确科室名称");
		showSearch.put("oldSection","原始科室名称");

		Map<String, Object> map = GetListUtil.getReturnMap2(totalSize, start, startIndex, endPage, list, null);
		map.put("showSearch", showSearch);
		//查询是否含有新增了同义词但没有新增其他的科室图片之类的
		List<StaticData> sds = staticDataDao.retrieveByCode("SECTION_ADD_WARN");
		List<StaticData > warnList = new ArrayList<>();
		if(sds!=null && sds.size()>0){
			for(StaticData sd :sds){
				warnList.add(sd);
			}
		}
		if(warnList.size()>0){
			map.put("warn", "1");
			map.put("warnList", warnList);
		}
		return new ModelAndView("section/index", map);
	}

	public ModelAndView edit(String id) {
		Map<String, Object> map = new HashMap<>();
		if (StringUtils.isNotBlank(id)) {
			Map<String, Object> param = new HashMap<>();
			param.put("id", id);
			SectionBlack value = sectionBlackDao.retrieveObjectById(Long.parseLong(id));
			if (value != null) {
				map.put("diseaseName", value.getDiseaseName());
				map.put("originalSection", value.getOriginalSection());
				map.put("id", value.getId());
				map.put("correctSection", value.getSectionId());
			}
		}
		return new ModelAndView("section/section_black_edit", map);
	}

	public ModelAndView deleteSectionBlack(String id, String startStr, String nameKey, String exactSearchFlag,
			String countPerPageStr,String section,String oldSection) {

		SectionBlack sc = new SectionBlack();
		sc.setId(Long.parseLong(id));
		sectionBlackDao.delete(sc);
		return list(startStr, nameKey, exactSearchFlag, countPerPageStr,section,oldSection);

	}

	public ReturnData sectionBlackAdd(String id, String diseaseName, String originalSection, String correctSection,
			String changeFlag, User user) {
		// 新增
		if (StringUtils.isBlank(id)) {
			SectionBlack sc = new SectionBlack();
			sc.setModifierId(user.getUserId() + "");
			sc.setDiseaseName(diseaseName);
			sc.setOriginalSection(originalSection);
			Map<String , Object> param = new HashMap<>();
			param.put("name", correctSection);
			List<Section> s = sectionDao.retrieveList(param);
			if(s.size()==1){
				sc.setSectionId(s.get(0).getId()+"");
			}else if(s.size()==0){
				//不存在需要新增
				Section value = new Section();
				value.setCnt(1);
				value.setDisable("0");
				value.setModifierId(user.getUserId());
				value.setName(correctSection);
				value.setSexAgeFlag(0);
				value.setSex(0);
				value.setAge("");
				Long sectionId = sectionDao.insert(value);
				sc.setSectionId(sectionId+"");
			}
			sectionBlackDao.insert(sc);
		} else {
			// 修改
			SectionBlack sc = sectionBlackDao.retrieveObjectById(Long.parseLong(id));
			Map<String , Object> param = new HashMap<>();
			param.put("name", sc.getSectionId());
			List<Section> sec = sectionDao.retrieveList(param);
			String oldSection = sec.get(0).getId()+"";
			String newSection = "";
			sc.setModifierId(user.getUserId() + "");
			sc.setDiseaseName(diseaseName);
			sc.setOriginalSection(originalSection);
			if(StringUtils.isNotBlank(correctSection)){
				param.clear();
				param.put("name", correctSection);
				List<Section> s = sectionDao.retrieveList(param);
				if(s.size()==1){
					sc.setSectionId(s.get(0).getId()+"");
					newSection =s.get(0).getId()+"";
				}else if(s.size()==0){
					//不存在需要新增
					Section value = new Section();
					value.setCnt(1);
					value.setDisable("0");
					value.setModifierId(user.getUserId());
					value.setName(correctSection);
					value.setSexAgeFlag(0);
					value.setSex(0);
					value.setAge("");
					Long sectionId = sectionDao.insert(value);
					sc.setSectionId(sectionId+"");
					newSection = sectionId+"";
				}
			}else{
				sc.setSectionId("0");
				newSection = "0";
			}
			sectionBlackDao.update(sc);
			//更新所有相同科室名称的记录到新的科室名称
			if(StringUtils.equals(changeFlag, "1")){
				sectionBlackDao.updateNewSection(oldSection, newSection,user.getUserId()); 
			}	
		}
		
		//校验黑名单科室是否都在同义词的标准科室名称
		checkData();
		//删除已经没有对应的section。已经失效
		sectionDao.deleteSectionInvalid();
		return ReturnUtil.success();
	}

	public void export(HttpServletResponse resp) throws Exception {
		Map<String, Object> param = new HashMap<>();
		// 获取已校验black列表
		RespHeaderUtil.setXlsxResp(resp, "section_black");
		List<SectionBlack> sectionList = sectionBlackDao.retrievesList(param);
		if (sectionList == null || sectionList.size() == 0) {
			return;
		}
		Workbook workbook = new XSSFWorkbook(); // 创建文档
		Sheet sheet = workbook.createSheet(); // 创建Sheet
		// 写入文件
		int i = 0;
		for (SectionBlack line : sectionList) {
			Row row = sheet.createRow(i);
			Cell cell1 = row.createCell(0);
			cell1.setCellValue(line.getDiseaseName());
			Cell cell2 = row.createCell(1);
			cell2.setCellValue(line.getOriginalSection());
			Cell cell3 = row.createCell(2);
			cell3.setCellValue(line.getSectionId());
			i++;
		}
		OutputStream os = resp.getOutputStream();
		workbook.write(os);
		os.close();
		workbook.close();		
	}

	/**
	 * 批量导入
	 * 
	 * @param user
	 * @param zipFile
	 * @return
	 * @throws IOException
	 */
	public ReturnData insertBatch(User user, MultipartFile file) throws IOException {
		if (file != null) { // 获取文件流，解析文件
			LOGGER.info("batch begin!");
			InputStream excelIn = file.getInputStream();
			InputStreamReader read = new InputStreamReader(excelIn, "UTF-8"); // 考虑到文本编码
			BufferedReader bf = new BufferedReader(read);
			Workbook workbook = new XSSFWorkbook(excelIn);
			Sheet sheet = workbook.getSheetAt(0);
			List<SectionBlack> insertList = new ArrayList<>();
			Map<String, Long> ksNameAndSectionId = new HashMap<>();
			//获取所有已经存在的科室名称对应编号
			List<Section> sts = sectionDao.retrieveList();
			for (Section st : sts) {
				ksNameAndSectionId.put(st.getName(), st.getId());
			}
			// 处理每一行
			for (Row row : sheet) {
				int i = 0;
				//取出每一行记录
				String diseaseName = "";
				String originalSection = "";
				String correctSection = "";
				for (Cell cell : row) {					
					//第一行跳过
					cell.setCellType(Cell.CELL_TYPE_STRING);
					String word = cell.getStringCellValue().trim();	
					if (i == 0) {
						diseaseName = word;
					} else if (i == 1) {
						originalSection = word;
					} else if (i == 2) {
						correctSection = word;
					}
					i++;
				}			

				SectionBlack value = new SectionBlack();
				value.setModifierId(user.getUserId() + "");
				if(StringUtils.isBlank(correctSection)){
					value.setSectionId("0");
				}else if(ksNameAndSectionId.get(correctSection) != null){
					value.setSectionId(ksNameAndSectionId.get(correctSection)+"");
				}else{
					//不存在需要新增
					Section sc = new Section();
					sc.setCnt(1);
					sc.setDisable("0");
					sc.setModifierId(user.getUserId());
					sc.setName(correctSection);
					sc.setSexAgeFlag(0);
					sc.setSex(0);
					sc.setAge("");
					Long sectionId = sectionDao.insert(sc);
					value.setSectionId(sectionId+"");
					ksNameAndSectionId.put(correctSection, sectionId);
				}
				value.setDiseaseName(diseaseName);
				value.setOriginalSection(originalSection);
				insertList.add(value);
			}
			if (insertList.size() > 0) {
				sectionBlackDao.deleteAll();
				sectionBlackDao.batchInsert(insertList);
			}
			//校验黑名单科室是否图片的科室名称
			checkData();
			//删除已经没有对应的section。已经失效
			sectionDao.deleteSectionInvalid();
			if(bf!=null){
				bf.close();
			}
			if(read != null){
				read.close();
			}
			return ReturnUtil.success("成功");
		} else {
			ReturnCode rc = ReturnCode.DYNAMIC_DESC_EXCEPTION;
			rc.setDesc("文件有误");
			return ReturnUtil.fail(rc);
		}
	}
	
	private void checkData(){
		LOGGER.info("check  blackSection begin!");
		//校验黑名单科室是否图片的科室名称
		List<String> checkBlack =  sectionBlackDao.checkBlackImageSection();
		StringBuffer errBlack = new StringBuffer();
		if(checkBlack != null && checkBlack.size()>0){
			for(String sc :checkBlack){
				if(errBlack.length()==0){
					errBlack.append("以下黑名单科室不在科室图片的科室名称中:");
				}
				errBlack.append(sc+";");
			}
		}
		if(errBlack.length()>0){
			throw new RuntimeException(errBlack.toString());
		}
		LOGGER.info("check  blackSection end!");

	}
}
